functor ReNumber (S : RENUMBER_STRUCTS) : RENUMBER =
struct
  open S
  
  structure Machine = Machine
 
  local open Machine
  in structure IdSet = IdSet
     structure B = Binop
     structure R = Register
     structure O = Operand
     structure K = Block
     structure S = Structs
     structure J = Transfer
     structure M = Stm
     structure F = Function
     structure P = Program
     structure Intl = Intl
     structure Id = Id
     structure T = Types
  end
  
  val tag = true
  fun debugPrint s =
      if tag
      then print (String.concat [s, "\n"])
      else ()
      
  val next = Counter.next
      
  fun transStm s =
      case s
       of M.Assign {line, dest, src, ty} =>
          M.Assign {line = next (), dest = dest, src = src, ty = ty}
        | M.AssignExp {line, dest, bop, src, ty} =>
          M.AssignExp {line = next (), dest = dest, bop = bop, src = src, ty = ty}
        | M.Alloc {line, fid, ty} =>
          M.Alloc {line = next (), fid = fid, ty = ty}
        | M.Call {line, fid, src, ty} =>
          M.Call {line = next (), fid = fid, src = src, ty = ty}
      
  fun transTransfer t =
      case t
       of J.Jump {line, label} =>
          J.Jump {line = next (), label = label}
        | J.If {line, value, truee, falsee} =>
          J.If {line = next (), value = value, truee = truee, falsee = falsee}
        | J.Return {line, value} =>
          J.Return {line = next (), value = value}
  
  fun transBlock b =
      case b
       of K.T {name, prop, stms, transfer, successors, ...} =>
          K.T {name = name,
               prop = prop,
               stms = List.map transStm stms,
               transfer = transTransfer transfer,
               successors = successors}       
               
  fun transFunc f = 
      case f
       of F.T {name, exit, rettype, args, locals, stackSize, blocks, pre, post} =>
          F.T {name = name,
               exit = exit,
               rettype = rettype,
               args = args,
               locals = locals,
               stackSize = stackSize,
               blocks = List.map transBlock blocks,
               pre = pre,
               post = post}
    
  fun transProg p =
      case p
       of P.T {structs,
               gvars,
               funcs} =>
          P.T {structs = structs,
               gvars = gvars,
               funcs = List.map transFunc funcs}
     
  fun renumber p =
      let val p = transProg p
      in  p
      end
end
